﻿using System;
using DynConDevCorp.OpenArch.SmartData.Interfaces.MetaData;

namespace DynConDevCorp.OpenArch.SmartData.Interfaces
{

    /// <summary>
    /// General Factory Interface for creating all Smart instances. By utilizing Factory and Builder design patterns,
    /// extremely flexible architectures can be implemented which utilize techniques such as Dependency Injection while
    /// not cluttering up the application code.
    /// </summary>
    public interface ISmartFactory
    {

        /// <summary>
        /// Creates the entity.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <returns></returns>
        ISmartEntity CreateEntityInstance(Type entityType);

        /// <summary>
        /// Creates the entity instance.
        /// </summary>
        /// <typeparam name="TTarget">The type of the target.</typeparam>
        /// <param name="EntityID">The entity ID.</param>
        /// <returns></returns>
        TTarget CreateEntityInstance<TTarget>(Guid EntityID)
           where TTarget : ISmartEntity;

        /// <summary>
        /// Creates the entity instance.
        /// </summary>
        /// <typeparam name="TTarget">The type of the target.</typeparam>
        /// <returns></returns>
        TTarget CreateEntityInstance<TTarget>()
           where TTarget : ISmartEntity;

        /// <summary>
        /// Creates the entity collection.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <returns></returns>
        ISmartEntityCollection CreateEntityCollection(Type entityType);

        /// <summary>
        /// Creates the field instance.
        /// </summary>
        /// <typeparam name="TData">Type of the data.</typeparam>
        /// <returns></returns>
        ISmartField<TData> CreateFieldInstance<TData>()
            where TData : IComparable<TData>;

        /// <summary>
        /// Creates the field instance.
        /// </summary>
        /// <param name="dataType">Type of the data.</param>
        /// <returns></returns>
        ISmartField CreateInstance(Type dataType);

        /// <summary>
        /// Creates the field instance.
        /// </summary>
        /// <param name="dataType">Type of the data.</param>
        /// <returns></returns>
        ISmartField CreateFieldInstance(Type dataType);

        /// <summary>
        /// Creates the entity instance.
        /// </summary>
        /// <returns></returns>
        ISmartEntity CreateEntityInstance();


        /// <summary>
        /// Creates the meta entity instance.
        /// </summary>
        /// <returns></returns>
        ISmartMetaEntity CreateMetaEntityInstance();

        /// <summary>
        /// Creates the input parser.
        /// </summary>
        /// <typeparam name="TData">The type of the AT a_ TYPE.</typeparam>
        /// <param name="handler">The handler.</param>
        /// <returns></returns>
        ISmartInputParser<TData> CreateInputParser<TData>(ParseHandler<TData> handler);

        /// <summary>
        /// Creates the display formatter.
        /// </summary>
        /// <typeparam name="TData">The type of the AT a_ TYPE.</typeparam>
        /// <param name="handler">The handler.</param>
        /// <returns></returns>
        ISmartDisplayFormatter<TData> CreateDisplayFormatter<TData>(ParseHandler<TData> handler)
            where TData : IComparable<TData>;
    }
}
